import { defineStore } from 'pinia'
import getFormConfigStore from './formConfig'
import api from '@/api'
import { collectionHelpers } from './modelStore'


function initializeFileStore(api) {
  return {
    state: () => ({
      api: api,
      loading: false,
      error: null,
      current: null,
      collection: [],
      collectionMetaData: {},
    }),
    actions: {
      loadFromNodes: async function (nodeIds) {
        await Promise.all(
          nodeIds.map(async (nodeId) => {
            const files = await this.api.getFiles(nodeId)
            this.collection.push(...files)
          })
        )
      },
      loadFromNode: async function (node_id) {
        const files = await this.api.getFiles(node_id)
        const file_by_ids = {}
        files.forEach((item) => {
          if (!file_by_ids[item.id]) {
            file_by_ids[item.id] = item
          }
        })
        const updatedFiles = []
        /** Update existing entries */
        const updatedItems = this.collection.map((item, index) => {
          if (file_by_ids[item.id]) {
            updatedFiles.push(item.id)
            return file_by_ids[item.id]
          } else {
            return item
          }
        })
        const newfiles = Object.values(file_by_ids).filter((file) => !updatedFiles.includes(file.id))
        this.collection = updatedItems.concat(newfiles)
        
      },
      addFile: async function (data) {
        this.loading = true
        console.log('Adding file from filestore')
        console.log(data)
        try {
          const fileObject = await this.api.create(data)
          this.collection = this.collection.concat([fileObject])
          this.current = fileObject
          this.error = null
          return fileObject
        } catch (e) {
          this.error = e
        } finally {
          this.loading = false
        }
      },
      addMultipleFiles: async function (filesFormData) {
        console.log('Adding multiple files from filestore')
        this.loading = true
        try {
          console.log('Building promises')
          const fileObjects = await Promise.all(
            filesFormData.map((data) => this.api.create(data))
          )
          this.collection = this.collection.concat(fileObjects)
          this.error = null
        } catch (e) {
          console.log(e)
          this.error = e
        } finally {
          this.loading = false
        }
      },
      updateFile: async function (data, fileId) {
        this.loading = true
        try {
          const fileObject = await this.api.update(data, fileId)
          this.collection = this.collection.map((item) => {
            if (item.id === fileId) {
              return fileObject
            } else {
              return item
            }
          })
          this.current = fileObject
          this.error = null
          return fileObject
        } catch (e) {
          console.log(e)
          this.error = e
        } finally {
          this.loading = false
        }
      },
      moveFile: async function (fileId, parentId) {
        this.loading = true
        try {
          const fileObject = await this.api.moveFile(fileId, parentId)
          const index = this.collection.findIndex((item) => item.id === fileId)
          this.collection[index] = fileObject
          this.current = fileObject
          this.error = null
        } catch (e) {
          this.error = e
        } finally {
          this.loading = false
        }
      },
      downloadFile: async function (fileId) {
        const fileUrl = `/files/${fileId}?action=download`
        window.open(fileUrl)
      },
      deleteFile: async function (fileId) {
        this.loading = true
        try {
          const fileObject = await this.api.delete(fileId)

          this.collection = this.collection.filter((item) => item.id !== fileId)
          this.current = fileObject
          this.error = null
        } catch (e) {
          this.error = e
        } finally {
          this.loading = false
        }
      },
    },
    getters: {
      getByParentId(state) {
        return (parentId, excludes = null, includes = null) => {
          console.log("Getting files by parent id", parentId)
          return state.collection.filter((item) => {
            if (item.parent_id != parentId) {
              return false
            }
            if (includes && !includes.includes(item.id)) {
              return false
            }
            if (excludes && excludes.includes(item.id)) {
              return false
            }
            return true
          })
        }
      },
      files(state) {
        return state.collection
      },
      ...collectionHelpers('files'),
    },
  }
}


// NOTE : Ce store ne doit être utilisé que pour 
// les fichiers rattachés à des Nodes
export const useFileStore = defineStore('files', initializeFileStore(api.files))

export const useCompanyLogoStore = defineStore('company_logo', initializeFileStore(api.company_logo))

export const useCompanyHeaderStore = defineStore('company_header', initializeFileStore(api.company_header))

export const useFileConfigStore = getFormConfigStore('files')
